package com.polaris.live.widget

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.view.View
import android.view.animation.Animation
import android.view.animation.BounceInterpolator
import android.view.animation.ScaleAnimation
import com.polaris.live.R
import com.polaris.live.utils.CommonUtils.arReverse

/**
 * AnimUtils
 *
 * @author Created by lucas on 2023/11/7 19:10
 */
object AnimUtils {

    fun clearAnimator(view: View) {
        val obj = view.getTag(R.id.anim_visible_tag) as? Animator ?: return
        obj.cancel()
        view.setTag(R.id.anim_visible_tag, null)
    }

    fun setTagAnimator(view: View, animator: Animator?) {
        view.setTag(R.id.anim_visible_tag, animator)
    }

    fun isPlaying(view: View): Boolean {
        return view.getTag(R.id.anim_visible_tag) != null
    }

    /**
     * 运行动画，会自动取消之前的动画
     *
     * @param view     视图
     * @param animator 动画
     */
    fun run(view: View, animator: Animator) {
        clearAnimator(view)

        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                setTagAnimator(view, null)
            }
        })
        animator.start()

        setTagAnimator(view, animator)
    }

    /**
     * 从左边进入
     */
    fun inLeft(
        view: View,
        width: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        return translationXAnim(view, -width, 0, builder, onFinish)
    }

    /**
     * 从左边出
     */
    fun outLeft(
        view: View,
        width: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: (View) -> Unit = { it.visibility = View.GONE },
    ): Animator {
        return translationXAnim(view, 0, -width, builder, onFinish)
    }

    /**
     * 从顶部进入
     */
    fun inTop(
        view: View,
        height: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        return translationYAnim(view, -height, 0, builder, onFinish)
    }

    /**
     * 从顶部出
     */
    fun outTop(
        view: View,
        height: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: (View) -> Unit = { it.visibility = View.GONE },
    ): Animator {
        return translationYAnim(view, 0, -height, builder, onFinish)
    }

    /**
     * 从右边进入
     */
    fun inRight(
        view: View,
        width: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        return translationXAnim(view, width, 0, builder, onFinish)
    }

    /**
     * 从右边出
     */
    fun outRight(
        view: View,
        width: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: (View) -> Unit = { it.visibility = View.GONE },
    ): Animator {
        return translationXAnim(view, 0, width, builder, onFinish)
    }

    /**
     * 从底部进入
     */
    fun inBottom(
        view: View,
        height: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        return translationYAnim(view, height, 0, builder, onFinish)
    }

    /**
     * 从底部出
     */
    fun outBottom(
        view: View,
        height: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: (View) -> Unit = { it.visibility = View.GONE },
    ): Animator {
        return translationYAnim(view, 0, height, builder, onFinish)
    }

    /**
     * 位移动画X
     */
    fun translationXAnim(
        view: View,
        start: Int,
        end: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        return translationAnim(view, start, end, "translationX", {
            builder?.invoke(this)

            view.translationX = 0f
        }, onFinish)
    }

    /**
     * 位移动画Y
     */
    fun translationYAnim(
        view: View,
        start: Int,
        end: Int,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        return translationAnim(view, start, end, "translationY", {
            builder?.invoke(this)

            view.translationY = 0f
        }, onFinish)
    }

    /**
     * 位移动画
     */
    private fun translationAnim(
        view: View,
        start: Int,
        end: Int,
        propertyName: String,
        builder: (ObjectAnimator.() -> Unit)? = null,
        onFinish: ((View) -> Unit)? = null,
    ): Animator {
        clearAnimator(view)


        val animator =
            ObjectAnimator.ofFloat(view, propertyName, start.toFloat(), end.arReverse.toFloat())
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                onFinish?.invoke(view)

                setTagAnimator(view, null)
            }
        })
        animator.duration = 350

        builder?.invoke(animator)

        animator.start()

        setTagAnimator(view, animator)

        return animator
    }

    fun getScaleAnimation(): Animation {
        val scaleAnimator = ScaleAnimation(
            0.5f,
            1f,
            0.5f,
            1f,
            Animation.RELATIVE_TO_SELF,
            0.5f,
            Animation.RELATIVE_TO_SELF,
            0.5f
        )
        scaleAnimator.duration = 500
        scaleAnimator.interpolator = BounceInterpolator()
        return scaleAnimator
    }

}